package com.frinder.official.akka.actors;

import akka.actor.*;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by frinder on 2017/9/12.
 * <p>
 * IndirectActorProducer 结合依赖注入容器（如：spring）实现 actor管理
 */
public class DependencyInjector implements IndirectActorProducer {

    /**
     * 依赖注入容器，如：spring applicationContext
     */
    final Map<String, TheActor> applicationContext;
    /**
     * bean 在依赖注入容器中的名称
     */
    final String beanName;

    public DependencyInjector(Map<String, TheActor> applicationContext, String beanName) {
        this.applicationContext = applicationContext;
        this.beanName = beanName;
    }

    /**
     * 返回 TheActor 类型
     *
     * @return
     */
    @Override
    public Class<? extends Actor> actorClass() {
        return TheActor.class;
    }

    /**
     * 生产 TheActor
     *
     * @return
     */
    @Override
    public TheActor produce() {
        TheActor result;
        // 从依赖注入容器中 get bean 对象
        result = applicationContext.get(beanName);
        return result;
    }

    static class TheActor extends AbstractActor {
        @Override
        public Receive createReceive() {
            return null;
        }
    }

    static class OtherActor extends AbstractActor {

        /**
         * 模拟依赖注入容器
         */
        final Map<String, TheActor> applicationContext = new HashMap() {{
            put("theActor", new TheActor());
        }};

        final ActorRef myActor = getContext().actorOf(
                Props.create(DependencyInjector.class, applicationContext, "theActor"),
                "the-actor"
        );

        @Override
        public Receive createReceive() {
            return null;
        }
    }
}
